package com.ruoyi.web.controller.biz;

import java.sql.Timestamp;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;

import com.ruoyi.biz.domain.ChipInfo;
import com.ruoyi.biz.domain.EquipmentInfo;
import com.ruoyi.biz.domain.SensorInfo;
import com.ruoyi.data.tdengine.domain.Sensor;
import com.ruoyi.data.tdengine.domain.SensorDataOfEquipment;
import com.ruoyi.data.tdengine.service.SensorService;
import com.ruoyi.biz.service.IChipInfoService;
import com.ruoyi.biz.service.IEquipmentInfoService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.biz.service.ISensorInfoService;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;

/**
 * 【请填写功能名称】Controller
 *
 * @author ruoyi
 * @date 2020-11-30
 */
@RestController
@RequestMapping("/system/sensor/info")
@Api(tags = "传感器")
public class SensorInfoController extends BaseController
{
    @Autowired
    private ISensorInfoService sensorInfoService;

    /*当用户接入传感器的时候需要新增tdengine中sensor的子表，表的名称为传感器code*/
    @Autowired
    private SensorService sensorService;

    @Autowired
    private IChipInfoService chipInfoService;
    @Autowired
    private IEquipmentInfoService equipmentInfoService;


    @ApiOperation("插入数据接口2,用这个")
    @GetMapping("/insert2/{sensorCode}/{value}")
    public AjaxResult insertData2(@PathVariable String sensorCode,@PathVariable Double value) {
        SensorInfo sensorInfo = sensorInfoService.selectSensorByCode(sensorCode);
        sensorService.insertSensorData(sensorCode,value, sensorInfo.getChipNum());
        return AjaxResult.success();
    }

    @ApiOperation("查询数据接口")
    @GetMapping("/select/{sensorCode}")
    public AjaxResult selectData(@PathVariable String sensorCode){
        List<Sensor> sensors = sensorService.selectSensorData(sensorCode);
        return AjaxResult.success(sensors);
    }

    @GetMapping("/sensor/name/{sensorName}")
    public AjaxResult getSensorByName(@PathVariable String sensorName){
        return AjaxResult.success(sensorInfoService.getSensorByName(sensorName));
    }
    /**
     * 获取全部传感器
     */
    @GetMapping("/sensor/all")
    public AjaxResult getAllSensors(){
        return AjaxResult.success(sensorInfoService.selectSensorInfoList(new SensorInfo()));
    }

    /**
     * 改变传感器的通知是否禁用状态
     * @return
     */
    @GetMapping("/change/{sensorId}/{status}")
    public AjaxResult ChangeStatus(@PathVariable Long sensorId,@PathVariable Integer status){
        SensorInfo sensorInfo = sensorInfoService.selectSensorInfoById(sensorId);
        logger.debug("修改对象:{}",sensorInfo);
        if (status==0){
            sensorInfo.setNoticeDisable(1);
        }else {
            sensorInfo.setNoticeDisable(0);
            sensorInfo.setNoticeNum(0);
            sensorInfo.setNoticeTime(null);
        }
        sensorInfoService.updateSensorInfo(sensorInfo);
        return AjaxResult.success();
    }

    @GetMapping("/sensorCode/{sensorCode}")
    public AjaxResult getSensor(@PathVariable String sensorCode){
        SensorInfo sensorInfo = sensorInfoService.selectSensorInfoById(sensorInfoService.selectSensorByCode(sensorCode).getSensorId());
        return AjaxResult.success(sensorInfo);
    }

    /**
     * 获取数据，渲染图表  查询过去一个月的数据，按一天来分析
     * @param sensorCode 超级表的具体子表表名
     */
    @ApiOperation("获取数据")
    @GetMapping("/data/{sensorCode}")
    public Map<String,List> getData(@PathVariable String sensorCode){
        long startTime = System.currentTimeMillis();
        List<Sensor> sensorList = new CopyOnWriteArrayList<>();
        try{
             sensorList  = sensorService.findTimeDataCount(sensorCode);
        }catch (Exception e){
            throw new RuntimeException("该传感器无数据");
        }
        SensorInfo sensorInfo = sensorInfoService.selectSensorByCode(sensorCode);
        String rule = getNumberDecimalDigits(sensorInfo.getAccuracy());
        logger.debug("处理规则：{}",rule);


        Map<String,List> listMap = new HashMap<>();
        List<String> list1 = new ArrayList<>();
        List<Double> doubleList  = new ArrayList<>();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        sensorList.forEach(item->{
            Timestamp ts = item.getTs();
            String format = simpleDateFormat.format(ts);
            list1.add(format);
            /**
             * 对数值进行处理，依照精度处理
             */
            DecimalFormat df = new DecimalFormat(rule);
            String str = df.format(item.getValue());
            doubleList.add(Double.valueOf(str));
        });
        listMap.put("ts",list1);
        listMap.put("value",doubleList);
        long endTime = System.currentTimeMillis();
        logger.debug("程序运行时间:{}" ,(endTime - startTime) + "ms");
        return listMap;
    }

    /**
     * 计算DecimalFormat转码规则的算法
     * @param number
     * @return
     */
    public static String getNumberDecimalDigits(double number) {
        StringBuilder str = new StringBuilder("#0.");
        if (number == (long)number) {
            return str.toString();
        }
        int i = 0;
        while (true){
            i++;
            str.append("0");
            if (number * Math.pow(10, i) % 1 == 0) {
                return str.toString();
            }
        }
    }

    /**
     * 查询【请填写功能名称】列表
     */
    @PreAuthorize("@ss.hasPermi('operate:sensor:info:list')")
    @GetMapping("/list")
    @ApiOperation("查询传感器信息列表")
    public TableDataInfo list(SensorInfo sensorInfo)
    {
        startPage();
        List<SensorInfo> list = sensorInfoService.selectSensorInfoList(sensorInfo);
        return getDataTable(list);
    }

    // 获取指定设备下的所有的传感器在指定时间范围的数据列表
    @ApiOperation("获取指定设备下的所有的传感器在指定时间范围的数据列表")
    @PostMapping("/findSensorDataOfEquipment")
    public List<Sensor> findSensorDataOfEquipment(@RequestBody SensorDataOfEquipment sensorDataOfEquipment) {
        return sensorService.findSensorDataOfEquipment(sensorDataOfEquipment);
    }

    /**
     * 导出【请填写功能名称】列表
     */
    @PreAuthorize("@ss.hasPermi('operate:sensor:info:export')")
    @Log(title = "【请填写功能名称】", businessType = BusinessType.EXPORT)
    @GetMapping("/export")
    @ApiOperation("导出传感器信息")
    public AjaxResult export(SensorInfo sensorInfo)
    {
        List<SensorInfo> list = sensorInfoService.selectSensorInfoList(sensorInfo);
        ExcelUtil<SensorInfo> util = new ExcelUtil<SensorInfo>(SensorInfo.class);
        return util.exportExcel(list, "info");
    }

    /**
     * 获取【请填写功能名称】详细信息
     */
    @PreAuthorize("@ss.hasPermi('operate:sensor:info:query')")
    @GetMapping(value = "/{sensorId}")
    @ApiOperation("获取传感器信息")
    public AjaxResult getInfo(@PathVariable("sensorId") Long sensorId)
    {
        SensorInfo sensorInfo = sensorInfoService.selectSensorInfoById(sensorId);
        Long chipId = sensorInfo.getChipId();
        ChipInfo chipInfo = chipInfoService.selectChipInfoById(chipId);
        Long equipmentId = chipInfo.getEquipmentId();
        EquipmentInfo equipmentInfo = equipmentInfoService.selectEquipmentInfoById(equipmentId);
        sensorInfo.setEquipmentId(equipmentId);
        sensorInfo.setEquipmentName(equipmentInfo.getEquipmentName());
        sensorInfo.setEmergencyContactName(equipmentInfo.getEmergencyContactName());
        return AjaxResult.success(sensorInfo);
    }

    /**
     * 新增【请填写功能名称】
     */
    @PreAuthorize("@ss.hasPermi('operate:sensor:info:add')")
    @Log(title = "【请填写功能名称】", businessType = BusinessType.INSERT)
    @PostMapping
    @ApiOperation("新增传感器信息")
    public AjaxResult add(@RequestBody SensorInfo sensorInfo)
    {
        // 转换对象
        Sensor sensor = new Sensor();
        if (sensorInfo != null) {
            // 获取传感器编码,判断是否已经存在
            String sensorCode = sensorInfo.getSensorCode();
            SensorInfo queryByCode = new SensorInfo();
            queryByCode.setSensorCode(sensorCode);
            List<SensorInfo> sensorInfos = sensorInfoService.selectSensorInfoList(queryByCode);
            if (sensorInfos != null && sensorInfos.size() > 0) {
                return AjaxResult.error("不可重复添加");
            }
            // 获取设备code
            String equipmentCode = sensorInfoService.getChipCodeById(sensorInfo.getChipId());
            sensor.setSensorCode(sensorCode);
            sensor.setEquipmentCode(equipmentCode);
        }
        // 新增传感器子表
        sensorService.addSensor(sensor);
        return toAjax(sensorInfoService.insertSensorInfo(sensorInfo));
    }


    /**
     * 新增【请填写功能名称】
     */
    @PreAuthorize("@ss.hasPermi('operate:sensor:info:add')")
    @Log(title = "【请填写功能名称】", businessType = BusinessType.INSERT)
    @PostMapping("/addSensorInfo/{chipId}")
    @ApiOperation("新增传感器信息")
    public AjaxResult addSensorInfo(@RequestBody SensorInfo sensorInfo,@PathVariable("chipId") Long chipId)
    {
        // 转换对象
        Sensor sensor = new Sensor();

        if (sensorInfo != null) {
            // 获取传感器编码,判断是否已经存在
            String sensorCode = sensorInfo.getSensorCode();
            SensorInfo queryByCode = new SensorInfo();
            queryByCode.setSensorCode(sensorCode);
            List<SensorInfo> sensorInfos = sensorInfoService.selectSensorInfoList(queryByCode);
            if (sensorInfos != null && sensorInfos.size() > 0) {
                return AjaxResult.error("不可重复添加");
            }
            // 芯片Code
            String equipmentCode = sensorInfoService.getChipCodeById(sensorInfo.getChipId());
            sensor.setSensorCode(sensorCode);
            sensor.setEquipmentCode(equipmentCode);
        }
        // 新增传感器子表
        sensorService.addSensor(sensor);
        return toAjax(sensorInfoService.insertSensorInfo(sensorInfo));
    }

    /**
     * 置顶
     * @param sensorId
     * @return
     */
    @GetMapping("/updateSensorTop/{sensorId}")
    public AjaxResult updateSensorTop(@PathVariable("sensorId") Long sensorId){
        sensorInfoService.updateSensorTop(sensorId);
        return AjaxResult.success();
    }
    /**
     * 修改【请填写功能名称】
     */
    @PreAuthorize("@ss.hasPermi('operate:sensor:info:edit')")
    @Log(title = "【请填写功能名称】", businessType = BusinessType.UPDATE)
    @PutMapping
    @ApiOperation("修改传感器信息")
    public AjaxResult edit(@RequestBody SensorInfo sensorInfo)
    {
        logger.debug("传感器对象精度：{}",sensorInfo.getAccuracy());
        return toAjax(sensorInfoService.updateSensorInfo(sensorInfo));
    }

    /**
     * 删除【请填写功能名称】
     */
    @PreAuthorize("@ss.hasPermi('operate:sensor:info:remove')")
    @Log(title = "【请填写功能名称】", businessType = BusinessType.DELETE)
	@DeleteMapping("/{sensorIds}")
    @ApiOperation("批量删除传感器信息")
    public AjaxResult remove(@PathVariable Long[] sensorIds)
    {
        return toAjax(sensorInfoService.deleteSensorInfoByIds(sensorIds));
    }

    /**
     * 传感器的启用和停用
     * @param sensorInfo
     * @return
     */
    @PreAuthorize("@ss.hasPermi('operate:sensor:info:enable:disabled')")
    @Log(title = "启用或停用设备")
    @PostMapping("/startOrStop")
    @ApiOperation("启用或停用设备")
    public AjaxResult startOrStopEquipment(@RequestBody SensorInfo sensorInfo) {
        return toAjax(sensorInfoService.startOrStopSensor(sensorInfo));
    }

    /**
     * 根据设备id获取传感器信息
     */
    @GetMapping("/selectSensorInfoByEquipmentId/{chipId}")
    @ApiOperation("根据芯片id获取传感器信息")
    public AjaxResult selectSensorInfoByEquipmentId(@PathVariable("chipId") Long chipId) {
        List<SensorInfo> sensorInfos = sensorInfoService.selectSensorInfoByChipId(chipId);
        if (sensorInfos != null && sensorInfos.size() > 0) {
            return AjaxResult.success(sensorInfos);
        }
        return toAjax(0);
    }


}
